#ifndef N1DELEGATE_H_2006_11_19
#define N1DELEGATE_H_2006_11_19

template<class T, class RET, class P1=void, class P2=void, class P3=void> 
class N1Delegate  { 
    T *m_ptr;
    typedef RET(T::*Function)(P1, P2, P3); 
    Function m_func;
    RET(T::*m_function)(P1, P2, P3); 
public: 
    RET call(P1 p1, P2 p2, P3 p3) { 
        return (m_ptr->*m_function)(p1, p2, p3);
    };
    N1Delegate(T* ptr, RET(T::*function)(P1, P2, P3)) 
        : m_ptr(ptr), m_function(function) { };
};

template<class T, class RET, class P1, class P2> 
class N1Delegate<T, RET, P1, P2, void> { 
    T *m_ptr;
    RET(T::*m_function)(P1, P2); 
public: 
    RET call(P1 p1, P2 p2) { 
        return (m_ptr->*m_function)(p1, p2);
    };
    N1Delegate(T* ptr, RET(T::*function)(P1, P2)) 
        : m_ptr(ptr), m_function(function) { };
};

template<class T, class RET, class P1> 
class N1Delegate<T, RET, P1, void, void> { 
    T *m_ptr;
    RET(T::*m_function)(P1); 
public: 
    RET call(P1 p1) { 
        return (m_ptr->*m_function)(p1);
    };
    N1Delegate(T* ptr, RET(T::*function)(P1)) 
        : m_ptr(ptr), m_function(function) { };
};

template<class T, class RET> 
class N1Delegate<T, RET, void, void, void> { 
    T *m_ptr;
    RET(T::*m_function)(); 
public: 
    RET call() { 
        return (m_ptr->*m_function)();
    };
    N1Delegate(T* ptr, RET(T::*function)()) 
        : m_ptr(ptr), m_function(function) { };
};

template<class T> 
class N1Delegate<T, void, void, void, void> { 
    T *m_ptr;
    void(T::*m_function)(); 
public: 
    void call() { 
        (m_ptr->*m_function)();
    };
    N1Delegate(T* ptr, void(T::*function)()) 
        : m_ptr(ptr), m_function(function) { };
};

#endif //N1DELEGATE_H_2006_11_19
